package com.xiaojian.blog.service.impl;

import com.xiaojian.blog.constant.WebConstant;
import com.xiaojian.blog.dao.MetaPOMapper;
import com.xiaojian.blog.dao.RelationshipPOMapper;
import com.xiaojian.blog.dto.MetaDto;
import com.xiaojian.blog.dto.Types;
import com.xiaojian.blog.exception.TipException;
import com.xiaojian.blog.model.ContentPO;
import com.xiaojian.blog.model.MetaPO;
import com.xiaojian.blog.model.MetaPOExample;
import com.xiaojian.blog.model.RelationshipPOKey;
import com.xiaojian.blog.service.ContentService;
import com.xiaojian.blog.service.MetaService;
import com.xiaojian.blog.service.RelationshipService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class MetaServiceImpl implements MetaService {

    private Logger LOGGER = LoggerFactory.getLogger(MetaServiceImpl.class);

    @Resource
    private MetaPOMapper metaPOMapper;

    @Resource
    private ContentService contentService;

    @Resource
    private RelationshipService relationshipService;

    @Override//根据类型和名字查询项
    public MetaDto getMeta(String type, String name) {
        if (StringUtils.isNotBlank(type) && StringUtils.isNotBlank(name)) {
            return metaPOMapper.selectDtoByNameAndType(name, type);
        }
        return null;
    }

    @Override//根据文章id获取项目个数
    public Integer countMeta(Integer mid) {
        return metaPOMapper.countWithSql(mid);
    }

    @Override//根据类型查询项目列表
    public List<MetaPO> getMetas(String types) {
        if (StringUtils.isNotBlank(types)) {
            MetaPOExample metaPOExample = new MetaPOExample();
            metaPOExample.setOrderByClause("sort desc, mid desc");
            return metaPOMapper.selectByExample(metaPOExample);
        }
        return null;
    }

    @Override//保存多个项目
    @Transactional
    public void saveMetas(Integer cid, String names, String type) {
        if (null == cid) {
            throw new TipException("项目关联id不能为空");
        }
        if (StringUtils.isNotBlank(names) && StringUtils.isNotBlank(type)) {
            String[] nameArr = StringUtils.split(names, ",");
            for (String name : nameArr) {
                this.saveOrUpdate(cid, name, type);
            }
        }
    }

    private void saveOrUpdate(Integer cid, String name, String type) {
        MetaPOExample example = new MetaPOExample();
        example.createCriteria().andTypeEqualTo(type).andNameEqualTo(name);
        List<MetaPO> metaPOS = metaPOMapper.selectByExample(example);

        int mid;
        MetaPO metaPO;
        if (metaPOS.size() == 1) {
            metaPO = metaPOS.get(0);
            mid = metaPO.getMid();
        }else if (metaPOS.size() > 1) {
            throw new TipException("查询到多条数据");
        }else {
            metaPO = new MetaPO();
            metaPO.setSlug(name);
            metaPO.setName(name);
            metaPO.setType(type);
            metaPOMapper.insertSelective(metaPO);
            mid = metaPO.getMid();
        }
        if (mid != 0) {
            Long count = relationshipService.countById(cid, mid);
            if (count == 0) {
                RelationshipPOKey relationshipPOKey = new RelationshipPOKey();
                relationshipPOKey.setCid(cid);
                relationshipPOKey.setMid(mid);
                relationshipService.insertVo(relationshipPOKey);
            }
        }
    }

    private String reMeta(String name, String metas) {
        String[] ms = StringUtils.split(metas, ",");
        StringBuilder sb = new StringBuilder();
        for (String m : ms) {
            if (!name.equals(m)) {
                sb.append(",").append(m);
            }
        }
        if (sb.length() > 0) {
            return sb.substring(1);
        }
        return "";
    }


    @Override//保存项目
    @Transactional
    public void saveMeta(String type, String name, Integer mid) {
        if (StringUtils.isNotBlank(type) && StringUtils.isNotBlank(name)) {
            MetaPOExample metaPOExample = new MetaPOExample();
            metaPOExample.createCriteria().andTypeEqualTo(type).andNameEqualTo(name);
            List<MetaPO> metaPOS = metaPOMapper.selectByExample(metaPOExample);
            MetaPO metaPO;
            if (metaPOS.size() != 0) {
                throw new TipException("已经存在该项");
            } else {
                metaPO = new MetaPO();
                metaPO.setName(name);
                if (null != mid) {
                    MetaPO original = metaPOMapper.selectByPrimaryKey(mid);
                    metaPO.setMid(mid);
                    metaPOMapper.updateByPrimaryKey(metaPO);
                    //更新原有文章的categories
                    contentService.updateCategory(original.getName(), name);
                }else {
                    metaPO.setType(type);
                    metaPOMapper.insertSelective(metaPO);
                }
            }
        }
    }

    @Override
    public List<MetaDto> getMetaList(String type, String orderby, int limit) {
        if (StringUtils.isNotBlank(type)) {
            if (StringUtils.isNotBlank(orderby)) {
                orderby = "count desc, a.mid desc";
            }
            if (limit < 1 || limit > WebConstant.MAX_POSTS) {
                limit = 10;
            }
            Map<String, Object> paraMap = new HashMap<>();
            paraMap.put("type", type);
            paraMap.put("order", orderby);
            paraMap.put("limit", limit);
            return metaPOMapper.selectFromSql(paraMap);
        }
        return null;
    }

    @Override
    @Transactional
    public void delete(int mid) {
        MetaPO metaPO = metaPOMapper.selectByPrimaryKey(mid);
        if (null != metaPO) {
            String type = metaPO.getType();
            String name = metaPO.getName();

            metaPOMapper.deleteByPrimaryKey(mid);

            List<RelationshipPOKey> rList = relationshipService.getRelationshipById(null, mid);
            if (null != rList) {
                for (RelationshipPOKey r : rList) {
                    ContentPO contents = contentService.getContents(String.valueOf(r.getCid()));
                    if (null != contents) {
                        ContentPO contentPO = new ContentPO();
                        contentPO.setCid(r.getCid());
                        if (type.equals(Types.CATEGORY.getType())) {
                            contentPO.setCategories(reMeta(name, contents.getCategories()));
                        }
                        if (type.equals(Types.TAG.getType())) {
                            contentPO.setTags(reMeta(name, contents.getTags()));
                        }
                        contentService.updateContentByCid(contentPO);
                    }
                }
            }
            relationshipService.deleteById(null, mid);
        }
    }

    @Override
    @Transactional
    public void saveMeta(MetaPO metaPO) {
        if (null != metaPO) {
            metaPOMapper.insertSelective(metaPO);
        }
    }

    @Override
    @Transactional
    public void update(MetaPO metaPO) {
        if (null != metaPO && null != metaPO.getMid()) {
            metaPOMapper.updateByPrimaryKeySelective(metaPO);
        }
    }
}
